package com.blb.common.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * RabbitMQ的配置
 */
@Slf4j
@Configuration
public class RabbitMQConfig {

    public static final String COURSE_SAVE_QUEUE = "edu-course-save-queue";
    public static final String COURSE_REMOVE_QUEUE = "edu-course-remove-queue";
    public static final String COURSE_EXCHANGE = "edu-course-exchange";
    public static final String COURSE_SAVE_KEY = "edu-course-save";
    public static final String COURSE_REMOVE_KEY = "edu-course-remove";

    /**
     * 保存课程的队列
     * @return
     */
    @Bean
    public Queue queueCourseSave() {
        return new Queue(COURSE_SAVE_QUEUE);
    }

    /**
     * 删除课程的队列
     * @return
     */
    @Bean
    public Queue queueCourseRemove() {
        return new Queue(COURSE_REMOVE_QUEUE);
    }

    /**
     * 主题模式的交换机
     * @return
     */
    @Bean
    public TopicExchange topicExchange() {
        return new TopicExchange(COURSE_EXCHANGE);
    }

    /**
     * 绑定保存课程队列和交换机
     * @return
     */
    @Bean
    public Binding bindCourseSave() {
        return BindingBuilder.bind(queueCourseSave()).to(topicExchange()).with(COURSE_SAVE_KEY);
    }

    /**
     * 绑定删除课程队列和交换机
     * @return
     */
    @Bean
    public Binding bindCourseRemove() {
        return BindingBuilder.bind(queueCourseRemove()).to(topicExchange()).with(COURSE_REMOVE_KEY);
    }

    /**
     * 配置自定义的Rabbit模板对象
     * @return
     */
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory){
        //创建自定义的rabbittemplate对象
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        //设置发布确认的回调方法
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            //确认回调 1.消息内容（包含id） 2.是否确认 3. 原因
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                if(ack){
                    log.info("消息发送成功 id:{}",correlationData);
                }else {
                    log.error("消息发送失败 id：{}，失败原因:{}", correlationData,
                            cause);
                }
            }
        });
        //设置返回机制的回调
        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
            //出现失败执行 参数：消息内容，响应代码，响应文本，交换机，路由键
            @Override
            public void returnedMessage(Message message, int code, String text, String exchange, String key) {
                log.error("消息：{}，代码：{}，文本：{}，交换机：{}，路由键：{}",
                        message,code,text,exchange,key);
            }
        });
        return rabbitTemplate;
    }

}
